Skip to content

feat(herdr): apply mate naming convention to workspace/tab labels - #30

Merged
trillium merged 5 commits into
mainfrom
fm/herdr-mate-naming-convention
Aug 2, 2026
Merged

feat(herdr): apply mate naming convention to workspace/tab labels#30
trillium merged 5 commits into
mainfrom
fm/herdr-mate-naming-convention

Conversation

@trillium

@trillium trillium commented Aug 2, 2026

Copy link
Copy Markdown
Owner

Intent

Implement a herdr workspace/tab naming convention so the captain can visually distinguish fleet supervisors (mates) from workers (crewmates) in herdr's UI at a glance. Convention: mate agents (persistent supervisors -- main firstmate plus every second/third mate) get workspace name AND tab name = {materank}-{scope}, ALWAYS UPPERCASE. materank: 1M=first mate/main firstmate, 2M=second mate, 3M=third mate. scope: the mate's domain (e.g. BEADME, PARLAY for second mates); main firstmate defaults to 1M-FIRSTMATE. Subordinate crewmates (workers spawned by any mate) are LOWERCASE, using the pre-existing fm- task label -- deliberately distinct from uppercase mate names and never colliding with one. Implementation: bin/backends/herdr.sh gets a new fm_backend_herdr_mate_scope helper (uppercases the secondmate marker id, sanitizes non-alphanumeric runs to a single dash, trims leading/trailing dashes, falls back to the literal UNKNOWN when empty/unreadable so a malformed marker can never impersonate the primary or collide) and fm_backend_herdr_workspace_label was rewritten to use it, producing 1M-FIRSTMATE for the primary home (no secondmate marker) and 2M- for a secondmate home. The projection-ordering jq helper is_top_level_parent was extended to also recognize the new ^[0-9]+M-[A-Z0-9-]+$ label shape while the old is_legacy_child matcher is deliberately left frozen (old-format-only) so a new-format parent can never spuriously match it -- this is a decision to keep old and new formats simultaneously recognized rather than migrating. bin/fm-spawn.sh was changed so a --secondmate spawn's own live-agent tab is labeled with the mate label (via fm_backend_herdr_workspace_label) instead of the ordinary fm- crewmate label; ordinary crewmate/scout spawns are unchanged. Docs (docs/herdr-backend.md new 'Mate naming convention' section, docs/configuration.md) were updated, including an explicit decision that pre-existing/older workspaces using the old firstmate/2ndmate- labels are NOT auto-migrated -- a captain must rename them manually, and this is called out as an intentional non-goal, not an oversight. Tests updated: fm-backend-herdr.test.sh (unit coverage for fm_backend_herdr_mate_scope and fm_backend_herdr_workspace_label, including the UNKNOWN fallback and uppercase-mate/lowercase-crewmate distinction), plus fake-herdr-binary label literals updated across fm-backend-herdr-launcher-workspace-e2e.test.sh, fm-backend-herdr-smoke.test.sh, fm-backend-herdr-workspace-per-home-e2e.test.sh, and fm-backend-herdr-presentation-e2e.test.sh (all e2e/smoke files were only syntax-checked via bash -n per this repo's hard safety rule against ever executing real-Herdr-lifecycle test paths by hand -- they are gated to skip without a live herdr binary). Also fixed a genuine regression surfaced only by actually running fm-session-start.test.sh: its make_fake_herdr_secondmate_recovery fake CLI's canned 'workspace list' response still hardcoded the OLD 2ndmate- label format, so bin/fm-bootstrap.sh's secondmate-liveness-sweep respawn path (which now searches for an existing workspace matching the NEW computed label before creating one) never found a match and failed; fixed by updating that fixture to emit the new 2M- format. Other backends (tmux, cmux, zellij) are confirmed unaffected -- this is a herdr-only change; fm-backend-cmux.test.sh and fm-backend-zellij.test.sh use their own independent, pre-existing 2ndmate- home-labeling convention unrelated to herdr's mate naming and were left untouched. All mocked/fakebin-based herdr test suites pass locally (145+33+41+ ok across files) and bin/fm-lint.sh is clean. PR should NOT be merged -- captain will review and merge manually.

What Changed

  • Added fm_backend_herdr_mate_scope to bin/backends/herdr.sh and rewrote fm_backend_herdr_workspace_label to use it, producing uppercase 1M-FIRSTMATE for the primary home and 2M-<SCOPE> for a secondmate home (sanitizing non-alphanumeric runs, trimming dashes, falling back to UNKNOWN on an empty/unreadable marker), while ordinary crewmate/scout labels remain the lowercase fm-<id> form.
  • Extended the projection-ordering is_top_level_parent jq helper to also recognize the new ^[0-9]+M-[A-Z0-9-]+$ label shape alongside the frozen legacy is_legacy_child matcher, and updated bin/fm-spawn.sh so a --secondmate spawn's live-agent tab is labeled with the mate label instead of the ordinary crewmate label.
  • Updated docs/herdr-backend.md and docs/configuration.md with a new mate naming convention section (including the explicit non-migration of pre-existing old-format workspaces), fixed a stale doc-comment label reference, noted that frozen herdr E2E evidence predates this convention, and updated unit/e2e/smoke test fixtures across the herdr test suite (plus a fm-session-start.test.sh fixture regression fix for the secondmate-liveness-sweep respawn path).

Risk Assessment

✅ Low: Change is a well-scoped, mechanical relabeling confined to the herdr backend (new fm_backend_herdr_mate_scope helper, updated workspace_label, and a HERDR_TASK_LABEL override for --secondmate spawns); it correctly fixes a real prior bug (an empty/malformed secondmate marker could previously impersonate the primary's "firstmate" label), the projection-ordering jq matcher is extended additively without breaking legacy-format recognition, and all touched test fixtures (unit, e2e, smoke) were updated consistently and verified against the new format including the genuine fm-session-start.test.sh fixture regression the author already caught and fixed.

Testing

Ran the two automated unit suites that changed for this feature (fm-backend-herdr.test.sh and fm-session-start.test.sh), both 100% passing including the new mate-naming-convention unit tests and the specific secondmate-liveness-sweep regression test the author fixed; syntax-checked the four e2e/smoke herdr test files without executing them (consistent with the repo's hard rule against running real Herdr lifecycle by hand, and a real herdr binary is installed here); and produced a CLI transcript that directly exercises the production label-computation code end-to-end, confirming the primary home resolves to 1M-FIRSTMATE, secondmate homes resolve to distinct uppercase 2M-<SCOPE> labels with correct sanitization and UNKNOWN fallback for malformed/blank markers, ordinary crewmate labels remain lowercase and are never misidentified as a mate workspace, and the projection-ordering jq helper accepts both the new and legacy label formats. No failures or missing-evidence gaps found.

Evidence: Herdr mate naming convention transcript (real code, all label/scope cases)

Primary home -> 1M-FIRSTMATE; secondmate 'beadme' -> 2M-BEADME; secondmate 'parlay' -> 2M-PARLAY; messy id ' fm.dev--Two!! ' -> 2M-FM-DEV-TWO; blank marker -> 2M-UNKNOWN (never impersonates 1M-FIRSTMATE); crewmate label fm-a1b2c3 stays lowercase and is correctly rejected by is_top_level_parent; legacy firstmate/2ndmate-<id> labels still accepted alongside new 1M-/2M- forms.

=== Demonstrating the herdr mate naming convention: workspace/tab labels a captain sees in herdr's UI ===

-- Primary firstmate home (no secondmate marker) --
workspace/tab label: 1M-FIRSTMATE

-- Second mate home, scope 'beadme' --
workspace/tab label: 2M-BEADME

-- Second mate home, scope 'parlay' (distinct from beadme's) --
workspace/tab label: 2M-PARLAY

-- Second mate home, messy marker id '  fm.dev--Two!!  ' (sanitization + uppercase) --
workspace/tab label: 2M-FM-DEV-TWO

-- Second mate home, malformed/blank marker (must never impersonate primary's 1M-FIRSTMATE) --
workspace/tab label: 2M-UNKNOWN

-- Ordinary crewmate/scout task label (unchanged, lowercase, never collides with an uppercase mate label) --
example crewmate tab label: fm-a1b2c3

-- Projection-ordering jq helper accepts both legacy and new-format parent labels --
{
  "new_primary": true,
  "new_secondmate": true,
  "old_primary": true,
  "old_secondmate": true,
  "crewmate_never_a_parent": false
}

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

✅ **Review** - passed

✅ No issues found.

✅ **Test** - passed

✅ No issues found.

  • bash tests/fm-backend-herdr.test.sh — 145/145 ok, including the new fm_backend_herdr_mate_scope and fm_backend_herdr_workspace_label cases (uppercase, sanitize/trim, UNKNOWN fallback, distinct secondmate labels)
  • bash tests/fm-session-start.test.sh — 33/33 ok, including test_session_start_relaunches_herdr_husk_secondmate which exercises the fixed regression (bootstrap secondmate-liveness-sweep now matches the fake CLI's 2M-<SCOPE> workspace-list fixture)
  • bash -n syntax-check on tests/fm-backend-herdr-launcher-workspace-e2e.test.sh, tests/fm-backend-herdr-smoke.test.sh, tests/fm-backend-herdr-workspace-per-home-e2e.test.sh, tests/fm-backend-herdr-presentation-e2e.test.sh — all parse cleanly; not executed by hand per this repo's own hard safety rule against running real-Herdr-lifecycle test paths outside the harness (a live herdr binary is present on this machine, so running them would attempt real workspace/tab lifecycle operations)
  • Manual CLI transcript sourcing the real bin/backends/herdr.sh and invoking fm_backend_herdr_workspace_label/fm_backend_herdr_mate_scope across primary-home, two distinct secondmate scopes, a messy marker id, and a blank marker, plus the projection-ordering jq is_top_level_parent helper against both legacy and new label shapes and a crewmate label
🔧 **Document** - 1 issue found → auto-fixed ✅
  • ℹ️ docs/verification/runtime-backends.md:218 - docs/verification/runtime-backends.md lines 215-221 record real live-Herdr E2E TAP output captured on 2026-07-30 that still literally shows the pre-change workspace label ('with one/two "firstmate" workspace(s)'). This is frozen evidence from an actual test run against real Herdr, not narrative prose, so it can't be corrected by a text edit without misrepresenting what was observed — it needs the real launcher-workspace-e2e suite re-run against live Herdr (which this repo's rules forbid running by hand in this context) to regenerate accurate dated evidence showing the new 1M-FIRSTMATE label.

🔧 Fix: Note frozen herdr E2E evidence predates mate naming convention
✅ Re-checked - no issues remain.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

Summary by CodeRabbit

  • New Features

    • Introduced clearer Herdr workspace labels: 1M-FIRSTMATE for primary workspaces and 2M-<SCOPE> for secondmate workspaces.
    • Secondmate task tabs now use their corresponding workspace labels.
    • Invalid or missing secondmate identifiers are labeled UNKNOWN.
    • Workspace ordering recognizes both new and legacy label formats.
  • Documentation

    • Updated configuration, naming conventions, upgrade guidance, and verification references for the new labels.
  • Tests

    • Expanded coverage for label normalization, workspace placement, isolation, recovery, and legacy compatibility.

Mates (main firstmate and secondmates) now get uppercase
<materank>-<scope> herdr workspace and tab labels (1M-FIRSTMATE,
2M-<SCOPE>), visually distinct from lowercase fm-<id> crewmate tabs,
so the captain can tell supervisors from workers in herdr's sidebar
at a glance.

- bin/backends/herdr.sh: add fm_backend_herdr_mate_scope (uppercase,
  sanitize, UNKNOWN fallback) and rewrite fm_backend_herdr_workspace_label
  to use it; extend is_top_level_parent to recognize the new format
  while keeping the legacy firstmate/2ndmate-<id> matcher frozen.
- bin/fm-spawn.sh: label a secondmate's own live-agent tab with its
  mate label instead of the ordinary fm-<id> task label.
- docs/herdr-backend.md, docs/configuration.md: document the
  convention and the no-migration caveat for pre-existing workspaces.
- tests: update herdr fixtures and fakebins to the new label format
  across fm-backend-herdr.test.sh, the launcher-workspace/smoke/
  workspace-per-home/presentation e2e suites, and fix a genuine
  regression in fm-session-start.test.sh's fake herdr secondmate
  recovery fixture that still emitted the old label format.
@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: e9ca9ec0-6dff-4f72-93c1-6244986876c4

📥 Commits

Reviewing files that changed from the base of the PR and between f72ed8b and 9fdd031.

📒 Files selected for processing (6)
  • bin/backends/herdr.sh
  • docs/herdr-backend.md
  • tests/fm-backend-herdr-prune-safety-e2e.test.sh
  • tests/fm-backend-herdr-workspace-per-home-e2e.test.sh
  • tests/fm-backend-herdr.test.sh
  • tests/fm-session-start.test.sh
🚧 Files skipped from review as they are similar to previous changes (5)
  • tests/fm-backend-herdr-workspace-per-home-e2e.test.sh
  • docs/herdr-backend.md
  • tests/fm-session-start.test.sh
  • bin/backends/herdr.sh
  • tests/fm-backend-herdr.test.sh

📝 Walkthrough

Walkthrough

Changes

Herdr workspace labels now use 1M-FIRSTMATE for primary homes and 2M-<SCOPE> for secondmate homes. Scope values are normalized with an UNKNOWN fallback. Spawn labels, workspace ordering, documentation, fixtures, and tests use the new convention.

Herdr workspace naming

Layer / File(s) Summary
Naming contract and workspace labels
bin/backends/herdr.sh, docs/configuration.md, docs/herdr-backend.md, docs/verification/runtime-backends.md, tests/fm-backend-herdr.test.sh
Adds secondmate scope normalization and updates workspace-label behavior, diagnostics, fixtures, lifecycle checks, and naming documentation.
Workspace ordering and projection
bin/backends/herdr.sh, tests/fm-backend-herdr-presentation-e2e.test.sh, tests/fm-backend-herdr.test.sh
Recognizes new-format parent labels and verifies child placement and ordering across primary and secondmate workspace blocks.
Spawn task labels and launcher placement
bin/fm-spawn.sh, tests/fm-backend-herdr-launcher-workspace-e2e.test.sh
Uses resolved secondmate labels for task tabs, task creation, diagnostics, and launcher workspace assertions.
Runtime and end-to-end coverage
tests/fm-backend-herdr-smoke.test.sh, tests/fm-backend-herdr-workspace-per-home-e2e.test.sh, tests/fm-session-start.test.sh, tests/fm-backend-herdr-prune-safety-e2e.test.sh
Updates smoke, per-home, restart-recovery, prune-safety, and fake Herdr workspace fixtures for the new labels.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Suggested reviewers: kunchenguid

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 26.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the Herdr mate naming convention applied to workspace and tab labels.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fm/herdr-mate-naming-convention

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@bin/backends/herdr.sh`:
- Around line 117-119: Update the fallback documentation in
bin/backends/herdr.sh at lines 117-119 to state only that "UNKNOWN" prevents an
empty workspace label, removing the claim that it prevents collisions; make the
corresponding clarification in docs/herdr-backend.md at line 74, noting that
multiple malformed markers may still share the 2M-UNKNOWN label.
- Line 145: Update the ID preprocessing before fm_backend_herdr_mate_scope so it
trims only leading and trailing whitespace while preserving embedded separators
for normalization; ensure an ID such as “alpha beta” produces the contracted
separated workspace label. Add a workspace-label test covering an embedded
separator.

In `@docs/herdr-backend.md`:
- Around line 61-62: Correct the legacy secondmate workspace label in the
documentation sentence by changing `firstmate-<id>` to `2ndmate-<id>`. Keep the
surrounding migration guidance unchanged.

In `@tests/fm-session-start.test.sh`:
- Around line 371-372: Update the recovery fixture’s label generation to match
the production normalization performed by fm_backend_herdr_mate_scope: trim and
sanitize the mate ID, uppercase it, and use UNKNOWN when the normalized value is
empty. Reuse that normalization behavior or pass the pre-normalized expected
scope into the fixture instead of only uppercasing FM_FAKE_SECOND_MATE_ID.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a66b0183-98dd-4aa3-adbf-046403de70cd

📥 Commits

Reviewing files that changed from the base of the PR and between 56369d0 and f72ed8b.

📒 Files selected for processing (11)
  • bin/backends/herdr.sh
  • bin/fm-spawn.sh
  • docs/configuration.md
  • docs/herdr-backend.md
  • docs/verification/runtime-backends.md
  • tests/fm-backend-herdr-launcher-workspace-e2e.test.sh
  • tests/fm-backend-herdr-presentation-e2e.test.sh
  • tests/fm-backend-herdr-smoke.test.sh
  • tests/fm-backend-herdr-workspace-per-home-e2e.test.sh
  • tests/fm-backend-herdr.test.sh
  • tests/fm-session-start.test.sh

Comment thread bin/backends/herdr.sh Outdated
Comment thread bin/backends/herdr.sh
Comment thread docs/herdr-backend.md Outdated
Comment thread tests/fm-session-start.test.sh Outdated
- correct comment/doc claims that the UNKNOWN scope fallback prevents
  collisions; it only guarantees non-empty, since every malformed
  marker shares the same UNKNOWN scope
- preserve internal separators in a secondmate marker id by trimming
  only outer whitespace before normalization, instead of stripping all
  whitespace first
- fix a stale legacy secondmate label in docs/herdr-backend.md
  (2ndmate-<id>, not firstmate-<id>)
- reuse fm_backend_herdr_mate_scope in the fake herdr session-start
  test fixture instead of duplicating simplified normalization logic

Addresses CodeRabbit review comments on PR #30.
@trillium
trillium merged commit 6bdc17a into main Aug 2, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant